home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / eckelt01.zip / 14 / TSTASH.H < prev    next >
C/C++ Source or Header  |  1995-02-23  |  5KB  |  164 lines

  1. // File from page 592 in "Thinking in C++" by Bruce Eckel
  2. //////////////////////////////////////////////////
  3. // From the compressed package ECKELT01.ZIP 2/21/95
  4. // Copyright (c) Bruce Eckel, 1995 
  5. // Source code file from the book "Thinking in C++", 
  6. // Prentice Hall, 1995, ISBN: 0-13-917709-4
  7. // All rights reserved EXCEPT as allowed by the following 
  8. // statements: You may freely use this file for your own 
  9. // work, including modifications and distribution in 
  10. // executable form only. You may copy and distribute this 
  11. // file, as long as it is only distributed in the complete 
  12. // (compressed) package with the other files from this 
  13. // book and you do not remove this copyright and notice. 
  14. // You may not distribute modified versions of the source 
  15. // code in this package. This package may be freely placed 
  16. // on bulletin boards, internet nodes, shareware disks and 
  17. // product vendor disks. You may not use this file in 
  18. // printed media without the express permission of the 
  19. // author. Bruce Eckel makes no 
  20. // representation about the suitability of this software 
  21. // for any purpose. It is provided "as is" without express 
  22. // or implied warranty of any kind. The entire risk as to 
  23. // the quality and performance of the software is with 
  24. // you. Should the software prove defective, you assume 
  25. // the cost of all necessary servicing, repair, or 
  26. // correction. 
  27. // If you think you've found an error, please 
  28. // email all modified files with loudly commented changes 
  29. // to: eckel@aol.com (please use the same 
  30. // address for non-code errors found in the book).
  31. //////////////////////////////////////////////////
  32.  
  33. //: TSTASH.H -- PSTASH using templates
  34. #ifndef TSTASH_H_
  35. #define TSTASH_H_
  36. #include <stdlib.h>
  37. #include "..\allege.h"
  38.  
  39. // Should be nested inside tstash; more
  40. // convenient global. You can move it:
  41. enum owns { no = 0, yes = 1, Default };
  42.  
  43. template<class Type, int chunksize = 20>
  44. class tstash {
  45.   int quantity;
  46.   int next;
  47.   owns own; // Flag
  48.   void inflate(int increase = chunksize);
  49. protected:
  50.   Type** storage;
  51. public:
  52.   tstash(owns Owns = yes);
  53.   ~tstash();
  54.   int Owns() const { return own; }
  55.   void Owns(owns newOwns) { own = newOwns; }
  56.   int add(Type* element);
  57.   int remove(int index, owns d = Default);
  58.   Type* operator[](int index);
  59.   int count() const { return next; }
  60.   friend class tstashIter<Type, chunksize>;
  61. };
  62.  
  63. template<class Type, int sz = 20>
  64. class tstashIter {
  65.   tstash<Type, sz>& ts;
  66.   int index;
  67. public:
  68.   tstashIter(tstash<Type, sz>& TS)
  69.     : ts(TS), index(0) {}
  70.   tstashIter(const tstashIter& rv)
  71.     : ts(rv.ts), index(rv.index) {}
  72.   // Jump interator forward or backward:
  73.   void forward(int amount) {
  74.     index += amount;
  75.     if(index >= ts.next) index = ts.next -1;
  76.   }
  77.   void backward(int amount) {
  78.     index -= amount;
  79.     if(index < 0) index = 0;
  80.   }
  81.   // Return value of ++ and -- to be 
  82.   // used inside conditionals:
  83.   int operator++() {
  84.     if(++index >= ts.next) return 0;
  85.     return 1;
  86.   }
  87.   int operator++(int) { return operator++(); }
  88.   int operator--() {
  89.     if(--index < 0) return 0;
  90.     return 1;
  91.   }
  92.   int operator--(int) { return operator--(); }
  93.   operator int() {
  94.     return index >= 0 && index < ts.next;
  95.   }
  96.   Type* operator->() {
  97.     Type* t = ts.storage[index];
  98.     if(t) return t;
  99.     allege(0,"tstashIter::operator->return 0");
  100.     return 0; // To allow inlining
  101.   }
  102.   // Remove the current element:
  103.   int remove(owns d = Default){
  104.     return ts.remove(index, d);
  105.   }
  106. };
  107.  
  108. template<class Type, int sz>
  109. tstash<Type, sz>::tstash(owns Owns) : own(Owns) {
  110.   quantity = 0;
  111.   storage = 0;
  112.   next = 0;
  113. }
  114.  
  115. // Destruction of contained objects:
  116. template<class Type, int sz>
  117. tstash<Type, sz>::~tstash() {
  118.   if(!storage) return;
  119.   if(own == yes)
  120.     for(int i = 0; i < count(); i++)
  121.       delete storage[i];
  122.   free(storage);
  123. }
  124.  
  125. template<class Type, int sz>
  126. int tstash<Type, sz>::add(Type* element) {
  127.   if(next >= quantity)
  128.     inflate();
  129.   storage[next++] = element;
  130.   return(next - 1); // Index number
  131. }
  132.  
  133. template<class Type, int sz>
  134. int tstash<Type, sz>::remove(int index,owns d){
  135.   if(index >= next || index < 0)
  136.     return 0;
  137.   switch(d) {
  138.     case Default:
  139.       if(own != yes) break;
  140.     case yes:
  141.       delete storage[index];
  142.     case no:
  143.       storage[index] = 0; // Position is empty
  144.   }
  145.   return 1;
  146. }
  147.  
  148. template<class Type, int sz> inline
  149. Type* tstash<Type, sz>::operator[](int index) {
  150.   // No check in shipping application:
  151.   assert(index >= 0 && index < next);
  152.   return storage[index];
  153. }
  154.  
  155. template<class Type, int sz>
  156. void tstash<Type, sz>::inflate(int increase) {
  157.   void* v = 
  158.     realloc(storage, (quantity+increase)*sizeof(Type*));
  159.   allegemem(v);  // Was it successful?
  160.   storage = (Type**)v;
  161.   quantity += increase;
  162. }
  163. #endif // TSTASH_H_
  164.